package com.geostar.gmp.thread;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 文件名:ThreadPoolManager.java
 * 功能: 线程池管理器
 * 目前支持方法
 * --------------------------------------
 * 初始版本 
 * 作者: yesong
 * 时间: Apr 10, 2014
 */
public class ThreadPoolManager {

	private static Logger logger = LoggerFactory.getLogger(ThreadPoolManager.class);
	
	private List<Future<Object>> futures = new ArrayList<Future<Object>>();
	private ExecutorService pool;
	
	//锁，用来记录线程的数量
	private final Lock lock = new Lock();
	
	public static final int DEFUALT_SIZE = 16;//默认线程池尺寸
	
	public ThreadPoolManager(){
		this(DEFUALT_SIZE);
	}

	public ThreadPoolManager(int poolSize) {
		pool = Executors.newFixedThreadPool(poolSize);
	}
	
	public void fork(AbstractJob job){
		job.setLock(lock);
		futures.add(pool.submit(job));
		synchronized (lock) {
			lock.thread_num++;
		}
	}
	
	@SuppressWarnings("unchecked")
	public List<Object> join(){
//		List<Object> resultList = new ArrayList<Object>();
		synchronized (lock) {
			//如果lock.thread_num小于0，则表示所有线程全部执行完毕
			while (lock.thread_num > 0){
				try {
					lock.wait();//如果任务没有全部完成，则挂起。等待完成的任务给予通知
				} catch (InterruptedException e) {
					e.printStackTrace();
				} 
			}
		}
		logger.info(">>>>>>>>>>>>>>所有线程执行完毕<<<<<<<<<<<<"); 
		
		// TODO 终止线程池任务的运行
		// pool.shutdown();
		
		// 在扫描过程中，只需要把取得的结果保存在数据库即可，即暂时没有汇总的方法
		// join方法现在只是保证线程池中的所有方法执行完毕，并且关闭线程池的运行
		/****
		Object result = null;
		for (Future<Object> future : futures) {
			try {
				result = future.get();
				if(result != null){
					if (result instanceof List){
						resultList.addAll((List)result);
					} else {
						resultList.add(result);
					}
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (ExecutionException e) {
				e.printStackTrace();
			}
		}
		****/
		return null;
	}

	public List<Future<Object>> getFutures() {
		return futures;
	}

	public void setFutures(List<Future<Object>> futures) {
		this.futures = futures;
	}
}
